package com.pactera.asmp.server.restfullapi;

import com.alibaba.fastjson.JSONObject;
import com.pactera.asmp.server.common.constants.PermissionCode;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.common.logprint.utils.CollectionUtils;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.entity.*;
import com.pactera.asmp.server.pojo.ScriptInfo;
import com.pactera.asmp.server.pojo.TaskStartupInfo;
import com.pactera.asmp.server.pojo.TestReport;
import com.pactera.asmp.server.service.ProjectModuleService;
import com.pactera.asmp.server.service.ScriptInfoServcieImpl;
import com.pactera.asmp.server.service.TaskService;
import com.pactera.asmp.server.service.TestReportServiceImpl;
import com.pactera.asmp.server.utils.AssertUtil;
import com.pactera.asmp.server.utils.PageDataResult;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @ProjectName: tlsserver
 * @Package com.pactera.asmp.server.restfullapi
 * @ClassName: RestfullTestReportApi
 * @Description: RestfullTestReportApi
 * @Date 2020/06/01 11:05
 * @Author lvzhiqiang
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/v1")
public class RestfullTestReportApi {

    private static final Logger logger = LoggerFactory
            .getLogger(RestfullTestReportApi.class);

    @Autowired
    private TestReportServiceImpl mTestReportServiceImpl;
    @Autowired
    private ScriptInfoServcieImpl mScriptInfoServcieImpl;

    @Autowired
    private ProjectModuleService projectModuleService;

    @Autowired
    private TaskService taskService;

    @Value("${minio.bucketName}")
    private String buckName;


    @RequiresPermissions({PermissionCode.TEST_TASK})
    @GetMapping(value = "/testreport",  produces = "application/json;charset=UTF-8")
    public ResponseResult getTestReport(@RequestParam("taskId") Integer taskId, @RequestParam("count") Integer count) {
        logger.info("/api/v1/script getTestReport taskId:{}, count:{}",taskId,count);

        AssertUtil.notNull(taskId,"任务Id参数异常");
        AssertUtil.notNull(count,"任务频次参数异常");
        TaskDTO taskById = taskService.getTaskById(taskId);
        String logType = "";
        if(taskById != null) {
             logType = taskById.getLogType();
        }
        //  临时处理，传入的taskId是t_task.id (应该是t_task_history.id),暂时行通过t_task.id 转换最后一次t_task_history.id，并查询数据
        TaskDTO task = taskService.getLastTaskHistoryByTaskId(taskId);
        if(task == null) throw new CustomException(ResultCode.DATA_IS_WRONG);
        taskId = task.getId();
        //--------------------------------------------------------------------------------------------------------------------------------

        //获取任务对应的项目模块
        List<ProjectModuleDTO>  moduleList = null;
        ResponseResult<List<ProjectModuleDTO>> moduleListResult = projectModuleService.selectAvailableByProjectId(task.getProjectId());
        if(moduleListResult.getCode() != ResultCode.SUCCESS.code()) throw new CustomException(ResultCode.BUSINESS_PROJECT_MODULE_BY_PROJECTID_ERR);
        moduleList = moduleListResult.getData();

        TestReportSearchDTO data = new TestReportSearchDTO();
        data.setPage(1);
        data.setLimit(Integer.MAX_VALUE);
        data.setTaskId(taskId);
        data.setCount(count);
        String minioFilePath = buckName + "/";
        PageDataResult pageDataResult = mTestReportServiceImpl.select(data);
        List<TestReport> testReports = (List<TestReport>) pageDataResult.getList();
        List<SelectTestReportResult> testReportResult = new ArrayList<>();
        for(TestReport report : testReports){
            SelectTestReportResult rt = new SelectTestReportResult();
            rt.setId(report.getId());
            rt.setAction(report.getAction());
            rt.setContent(report.getContent());
            rt.setBugId(report.getBugId());
            rt.setBugUrl(report.getBugUrl());
            rt.setPerformanceData(report.getPerformanceData());
            rt.setMonkeyOrder(report.getMonkeyOrder());
            rt.setMonkeyReport(report.getMonkeyReport());
            rt.setCount(report.getCount());
            rt.setStatus(report.getStatus());
            rt.setVideoFileIndex(minioFilePath + report.getVideoFileIndex());
            rt.setLogFileIndex(minioFilePath + report.getLogFileIndex());
            rt.setHtmlReportFileId(minioFilePath + report.getHtmlReportFileId());
            rt.setCanLogFileId(minioFilePath + report.getCanLogFileId());
            rt.setCreateTime(report.getCreateTime());
            if(null != report.getScriptId()) {
                ScriptInfo scriptInfo = mScriptInfoServcieImpl.selectScriptByScriptId(report.getScriptId());
                if(scriptInfo != null) {
                    rt.setScriptJson(scriptInfo.getScriptData());
                }
            }
            rt.setErrorVideoInfos(mTestReportServiceImpl.getErrorVideoInfosByTestReportId(report.getId()));
            rt.setTestedReport(mTestReportServiceImpl.getTestReportApplicationResponseTime(taskId));

            rt.setScriptName(report.getScriptName());
            rt.setModuleName(getModuleName(report.getModuleId(),moduleList));
            testReportResult.add(rt);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("logType",logType);
        jsonObject.put("totals",testReportResult.size());
        jsonObject.put("list", testReportResult);
        HashMap<String ,List<TaskStartupInfo>> map = new HashMap<>();
        List<TaskStartupInfo> taskStartupInfos = mTestReportServiceImpl.getTaskStartupInfo(taskId);
        if(CollectionUtils.isNotEmpty(taskStartupInfos)) {
            for (TaskStartupInfo taskStartupInfo : taskStartupInfos){
                List<TaskStartupInfo> list = map.get(taskStartupInfo.getPackageName());
                if(list == null){
                    list = new ArrayList<>();
                    map.put(taskStartupInfo.getPackageName(), list);
                }
                list.add(taskStartupInfo);
            }
        }
        jsonObject.put("coldHotReport", map);
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        responseResult.setData(jsonObject);
        return responseResult;
    }

    private String getModuleName(Integer moduleId,List<ProjectModuleDTO> moduleList) {
        if(CollectionUtils.isEmpty(moduleList) || null == moduleId) return  null;
        for(ProjectModuleDTO dto : moduleList){
            if(moduleId.equals(dto.getId())){
                return dto.getName();
            }
        }
        return null;
    }

    @GetMapping(value = "/testreportall", produces = "application/json;charset=UTF-8")
    public ResponseResult getTestReportAllByTaskId(@RequestParam("taskId") Integer taskId) {
        logger.info("/api/v1/script getTestReportAllByTaskId taskId:{}",taskId);

        // 获取任务信息
        //  临时处理，传入的taskId是t_task.id (应该是t_task_history.id),暂时行通过t_task.id 转换最后一次t_task_history.id，并查询数据
        TaskDTO lastTaskHistoryByTaskId = taskService.getLastTaskHistoryByTaskId(taskId);
        if(lastTaskHistoryByTaskId == null) throw new CustomException(ResultCode.DATA_IS_WRONG);
        taskId = lastTaskHistoryByTaskId.getId();
        //--------------------------------------------------------------------------------------------------------------------------------


        List<SelectTestReportResult> list = mTestReportServiceImpl.selectAll(taskId);
        //获取任务对应的项目模块
        List<ProjectModuleDTO>  moduleList = null;
        ResponseResult<List<ProjectModuleDTO>> moduleListResult = projectModuleService.selectAvailableByProjectId(lastTaskHistoryByTaskId.getProjectId());
        if(moduleListResult.getCode() != ResultCode.SUCCESS.code()) throw new CustomException(ResultCode.BUSINESS_PROJECT_MODULE_BY_PROJECTID_ERR);
        moduleList = moduleListResult.getData();
        String minioFilePath = buckName + "/";
        for(SelectTestReportResult rt : list){
            rt.setId(rt.getId());
            rt.setAction(rt.getAction());
            rt.setContent(rt.getContent());
            rt.setCount(rt.getCount());
            rt.setStatus(rt.getStatus());
            rt.setVideoFileIndex(minioFilePath + rt.getVideoFileIndex());
            rt.setLogFileIndex(minioFilePath + rt.getLogFileIndex());
            rt.setCreateTime(rt.getCreateTime());
            rt.setScriptJson(mScriptInfoServcieImpl.selectScriptByScriptId(rt.getScriptId()).getScriptData());

            rt.setScriptName(rt.getScriptName());
            rt.setModuleName(getModuleName(rt.getModuleId(),moduleList));
        }
        return ResponseResult.defaultSuccess(list);
    }


    @RequiresPermissions({PermissionCode.TEST_TASK})
    @GetMapping(value = "/reportByTask", produces = "application/json;charset=UTF-8")
    public ResponseResult getTestReportDataByTask(@RequestParam("taskId") Integer taskId) {
        logger.info("/api/v1/script getTestReportData taskId:{}" ,taskId);
        return  this.mTestReportServiceImpl.getTestReportDataByTask(taskId);
    }

    @RequiresPermissions({PermissionCode.TEST_TASK})
    @GetMapping(value = "/reportByTaskScripts",  produces = "application/json;charset=UTF-8")
    public ResponseResult getTestReportDataByTaskScripts(@RequestParam("taskId") Integer taskId) {
        logger.info("/api/v1/script reportByTaskScripts taskId:{}" ,taskId);
        return  this.mTestReportServiceImpl.getTestReportDataByTaskScripts(taskId);
    }

    @RequiresPermissions({PermissionCode.TEST_OVERVIEW})
    @GetMapping(value = "/reportByProject",produces = "application/json;charset=UTF-8")
    public ResponseResult getTestReportDataByProject(@RequestParam("projectId") Integer projectId) {
        logger.info("GET /api/v1/reportByProject:{}" ,projectId);
        return  this.mTestReportServiceImpl.getTestReportDataByProject(projectId);
    }

    @GetMapping("/reports/fails")
    public ResponseResult getFailReports(@RequestParam("taskId") Integer taskId,@RequestParam("moduleId") Integer moduleId){
        logger.info("GET /api/v1/reports/fails: {}---{}" ,taskId,moduleId);
        return mTestReportServiceImpl.getFailReports(taskId,moduleId);
    }

    /**
     * @api {GET} /api/v1/file/log/{fileName} getFileLog
     * @apiVersion 1.0.0
     * @apiGroup RestfullTestReportApi
     * @apiName getFileLog
     * @apiDescription 使用文件名从后端获取log文件
     * @apiParam (请求参数) {String} fileName 文件名
     * @apiParamExample 请求参数示例
     * fileName=1TnlKcrky
     * @apiHeader {String} Authorization Bearer xxx
     * @apiHeaderExample {json} Request-Example:
     * { "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiNTAiLCJjaGFubmVsSWQiOjUsInJvbGVJZCI6IjIiLCJjcmVhdGVUaW1lIjoxNjE1MzU5MDgxNDY1LCJsb2NhbGhvc3QiOiJCQUIxOTAwMjE1Iiwic3ViIjoiYWRtaW4iLCJpc3MiOiIyZDBhNDI2MTY5MjYwYzA4NmIxNWU4MzlhYmEyMGUwOSIsImlhdCI6MTYxNTM1OTA4MSwiYXVkIjoicmVzdGFwaXVzZXIiLCJleHAiOjE2MTc5NTEwODEsIm5iZiI6MTYxNTM1OTA4MX0.BpUVtIE4kWyWKD8-b7lAv1611rv5N1U1q0VO4ijD0P0" }
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccessExample 响应结果示例
     * {"code":5518,"data":{},"message":"oLfXi"}
     */
    @GetMapping("/file/log/{fileName}")
    public ResponseResult getFileLog(@PathVariable String fileName){
        logger.info("GET /api/v1/file/log/{fileName}: fileName: {}", fileName);
        if (StringUtils.isEmpty(fileName)) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        return mTestReportServiceImpl.getFileLog(fileName);
    }
}
